package com.huo.com.redisLock.service;

import com.alibaba.fastjson.JSON;
import com.huo.com.redisLock.dao.StockDao;
import com.huo.com.redisLock.entity.TestStock;
import com.huo.com.redisLock.lock.TestLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.util.Map;


@Component
public class TestStockService {

    @Autowired
    private StockDao stockDao;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired
    private TransactionDefinition transactionDefinition;

    //锁定数据库
    public void getStock(Map<String,String> param){

        //获取锁
        TestLock testLock=new TestLock(redisTemplate);
        boolean lock = testLock.getLock(param.get("goodsId").toString(), param.get("userId").toString());

        TransactionStatus transaction=null;

        try{
            if(lock){//获取到锁
                //查询库存
                TestStock stock = stockDao.getStock(param);
                //更新库存
                if(stock.getStock()>=1){//判断库存足不足
                    stock.setStock(stock.getStock()-1);//将库存做减1的操作，模拟锁定库存，实际业务中，根据设定的锁定量锁定库存

                    //开启事务
                    transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);

                    //进行库存减少1操作
                    int i = stockDao.updateStock(stock);

                    //写库存流水
                    System.out.println("------更新库存----"+i);

                    //写入订单

                    //提交事务
                    dataSourceTransactionManager.commit(transaction);

                    //释放锁
                    testLock.unLock(param.get("goodsId").toString(), param.get("userId").toString());
                    testLock=null;
                }else{
                    //释放锁
                    testLock.unLock(param.get("goodsId").toString(), param.get("userId").toString());
                    testLock=null;
                    throw new RuntimeException("库存不足");
                }

            }else{
                //假如没有获取到锁，将没有获取到锁的请求加入队列，或者是定时任务，这里选择redis的消息队列
                String string = JSON.toJSONString(param);
                redisTemplate.convertAndSend("LOCK",string);
            }

        }catch (Exception e){
            //回滚事务
            dataSourceTransactionManager.rollback(transaction);
            //释放锁
            testLock.unLock(param.get("goodsId").toString(), param.get("userId").toString());
            e.printStackTrace();
        }


    }

}
